package cc.lj.internal.coupons.application.service;

import cc.lj.internal.api.ordershare.dto.OrderOnlineAPIDTO;
import cc.lj.internal.api.ordershare.dto.OrderPaymentAPIDTO;
import cc.lj.internal.core.exception.ServiceException;
import cc.lj.internal.coupons.application.FeignAppService;
import cc.lj.internal.coupons.application.utils.TicketUtil;
import cc.lj.internal.coupons.domain.martcap.model.vo.BatchBindRelationDO;
import cc.lj.internal.coupons.domain.ticket.model.vo.TicketBatchDO;
import cc.lj.internal.coupons.domain.ticket.model.vo.TicketMainDO;
import cc.lj.internal.coupons.domain.ticket.model.vo.convert.TicketMainPOConvertDO;
import cc.lj.internal.coupons.domain.ticket.repository.IUseTicketCheckCacheRepository;
import cc.lj.internal.coupons.domain.ticket.service.*;
import cc.lj.internal.coupons.domain.ticket.service.impl.useTicketRule.FindFirstStepUtil;
import cc.lj.internal.coupons.infrastructure.excepion.CoupousExceptionEnum;
import cc.lj.internal.coupons.infrastructure.po.TicketMainPO;
import cc.lj.internal.coupons.interfaces.dto.TicketMainDTO;
import cc.lj.internal.coupons.interfaces.dto.command.DeleteUseTicketCheckCommand;
import cc.lj.internal.coupons.interfaces.dto.command.UseTicketCheckCommand;
import cc.lj.internal.coupons.interfaces.dto.convert.TicketMainDTOConvertDO;
import lj.internal.dict.enums.ticketBatch.EnumTicketSingleStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 取消用券验证 app service
 * @author liangxifeng
 * @date 2023/6/12 17:34
 */
@Service
@Slf4j
public class DeleteUseTicketCheckAppService {
    //电子券主表 domain service
    @Resource(name = "ticketMainDomainServiceImpl")
    private ITicketMainDomainService ticketMainDomainService;
    //电子券批次表 domain service
    @Resource(name = "ticketBatchDomainServiceImpl")
    private ITicketBatchDomainService ticketBatchDomainService;
    //删除用券 domain service
    @Resource(name = "deleteUseTicketDomainServiceImpl")
    private IDeleteUseTicketDomainService deleteUseTicketDomainService;
    //redis 缓存仓储接口
    @Resource(name = "usetTicketCheckCacheRedisRepositoryImpl")
    private IUseTicketCheckCacheRepository cacheRepository;
    //券批次绑定关系表 domain service
    @Resource(name = "batchBindRelationDomainServiceImpl")
    private IBatchBindRelationDomainService relationDomainService;

    public List<String> doMain(DeleteUseTicketCheckCommand checkCommand) {
        //通过使用码查询电子券主表数据
        TicketMainDO ticketMainDOParm = new TicketMainDO();
        //电子券使用码添加 * 号前缀
        String useCode = TicketUtil.addPrefixUseCode(checkCommand.getTicketUseCode());
        //这里command中的电子券使用码为没有*前缀的，因为要操作redis
        checkCommand.setTicketUseCode(TicketUtil.delPrefixUseCode(useCode));
        ticketMainDOParm.setTicketUseCode(useCode);
        List<TicketMainDO> ticketMainDOList = ticketMainDomainService.getList(ticketMainDOParm);
        TicketMainDO ticketMainDO = ticketMainDOList.size() == 1 ? ticketMainDOList.get(0) : null;
        log.info("【取消用券验证电子券】开始,command："+checkCommand+"券主表数据:"+ticketMainDO);
        //打印该合同在redis中所有数据结构
        cacheRepository.printAll(checkCommand.getPactNum(),checkCommand.getUuId());
        if(ticketMainDO == null)
        {
            throw new ServiceException(CoupousExceptionEnum.GET_TICKET_MAIN_BY_USECODE_IS_NULL);
        }
        //通过主键查询电子券批次表
        TicketBatchDO ticketBatchDO = ticketBatchDomainService.getById(ticketMainDO.getTicketBatchId());

        /**
         * 验证是否是主券, 如果主券有副券，且副券存在于redis已用券列表中，则将主券和这些副券一起删除
         */
        //最终需要删除的券使用码list
        List<String> delUseCodeList = new ArrayList<>();

        //如果该批次电子券 不是独立使用券 且 在绑定关系表装存在 主券，则删除的这券是主券
        if(ticketBatchDO.getSingleFlag() == EnumTicketSingleStatus.NOT_SINGLE.getCode()) {
            BatchBindRelationDO relationDOParam = new BatchBindRelationDO();
            relationDOParam.setMainBatchId(ticketBatchDO.getBatchId());
            List<BatchBindRelationDO> relationDOList = relationDomainService.getList(relationDOParam);
            log.info("【取消用券验证电子券】通过主券批次主键查询绑定关系表数据："+relationDOList);
            //关系表存在主券
            List<Integer> childBatchIdList = new ArrayList<>(); // 定义副券主键list
            if(relationDOList.size() > 0) {
                //将副券批次主键 新增到 childBatchIdList 中
                relationDOList.forEach(batchBindRelationDO -> childBatchIdList.add(batchBindRelationDO.getChildBatchId()));
                //从redi中读取已用券数据 Map<券使用码=>券批次主键>
                Map<String,Integer> redisTickets = cacheRepository.getUseTicketList(checkCommand.getPactNum(),checkCommand.getUuId());
                if(redisTickets.size() > 0) {
                    for (Map.Entry<String, Integer> entry : redisTickets.entrySet()) {
                        //查看已用券列表中是否包含 副券，如果包含，则一并删除
                        if(childBatchIdList.contains(entry.getValue()) ) {
                            //将副券使用码放到需要删除的使用码list中
                            delUseCodeList.add(entry.getKey());
                        }
                    }
                }
            }
        }
        log.info("【取消用券验证电子券】主券使用码："+ checkCommand.getTicketUseCode()+",batchId:"+ticketBatchDO.getBatchId()+",需要连带删除的副券使用码："+delUseCodeList);
        delUseCodeList.add(checkCommand.getTicketUseCode()); //将主券使用码放入删除的使用码List中去
        //循环删除用券数据
        delUseCodeList.forEach(x->{
            checkCommand.setTicketUseCode(x);
            //删除用券操作
            deleteUseTicketDomainService.deleteMain(ticketBatchDO,checkCommand);
        });

        log.info("【取消用券验证电子券】使用码全部删除成功,成功删除的券使用码List:"+delUseCodeList);
        return delUseCodeList;
    }
}
